package com.octant.testble;

import androidx.appcompat.app.AppCompatActivity;

import android.Manifest;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothGatt;
import android.bluetooth.BluetoothGattCallback;
import android.bluetooth.BluetoothGattCharacteristic;
import android.bluetooth.BluetoothGattDescriptor;
import android.bluetooth.BluetoothGattService;
import android.bluetooth.BluetoothManager;
import android.bluetooth.BluetoothProfile;
import android.bluetooth.le.BluetoothLeScanner;
import android.bluetooth.le.ScanCallback;
import android.bluetooth.le.ScanResult;
import android.content.Context;
import android.content.DialogInterface;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.text.method.ScrollingMovementMethod;
import android.util.Log;
import android.view.View;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

public class MainActivity extends AppCompatActivity implements View.OnClickListener {

    String TAG = "MainActivity";

    boolean USE_SPECIFIC_UUID = false;//使用特定的UUID
    //定义需要进行通信的ServiceUUID
    private UUID mServiceUUID = UUID.fromString("0000ffe0-0000-1000-8000-00805f9b34fb");
    //定义需要进行通信的CharacteristicUUID
    private UUID mCharacteristicUUID = UUID.fromString("0000ffe4-0000-1000-8000-00805f9b34fb");

    private BluetoothAdapter mBluetoothAdapter;
    private BluetoothManager bluetoothManager;
    private BluetoothLeScanner mBLEScanner;
    private boolean mScanning;//是否正在搜索
    private Handler mHandler;
    private final int SCAN_TIME = 3000;
    private ArrayList<BluetoothDevice> bluetoothDeviceArrayList = new ArrayList<>();
    int selIndex = 0;
    private boolean[] mConnectionState = new boolean[]{false,false,false,false} ;//是否正在连
    private BluetoothGatt[] mBluetoothGatt = new BluetoothGatt[4];
  //  private ArrayList<BluetoothGattCharacteristic> writeCharacteristicArrayList = new ArrayList<>();//需要先把可写的Characteristic添加进去
   // private ArrayList<BluetoothGattCharacteristic> readCharacteristicArrayList = new ArrayList<>();//需要先把可写的Characteristic添加进去
    private List<List<BluetoothGattCharacteristic>> fourWriteCharacteristicArrayList = new ArrayList<>();
    private List<List<BluetoothGattCharacteristic>> fourReadCharacteristicArrayList = new ArrayList<>();
    private List<List<BluetoothGattCharacteristic>> fourNotifyCharacteristicArrayList = new ArrayList<>();

    private Button btn_show_ble1,btn_show_ble2,btn_show_ble3,btn_show_ble4,btn_ble,btn_clear_receive_data,btn_send_data;
    private TextView tv_device_name;
    private EditText edt_receive_data,edt_send_data;

    private int show_ble = 0;
    private String[] device_name = new String[]{"","","",""};

    ProgressDialog waitDialog;
    ProgressDialog cancelDialog;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initPermission();
        initViews();

        //首先获取BluetoothManager
        bluetoothManager=(BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
        //获取BluetoothAdapter
        if (bluetoothManager != null) {
            mBluetoothAdapter = bluetoothManager.getAdapter();
        }
        mHandler = new Handler();
        for (int i=0; i<4; i++){
            ArrayList<BluetoothGattCharacteristic> writeCharacteristicArrayList = new ArrayList<>();
            fourWriteCharacteristicArrayList.add(writeCharacteristicArrayList);
            ArrayList<BluetoothGattCharacteristic> readCharacteristicArrayList = new ArrayList<>();
            fourReadCharacteristicArrayList.add(readCharacteristicArrayList);
            ArrayList<BluetoothGattCharacteristic> notifyCharacteristicArrayList = new ArrayList<>();
            fourNotifyCharacteristicArrayList.add(notifyCharacteristicArrayList);
        }
    }

    //申请多个权限
    //1、首先声明一个数组permissions，将需要的权限都放在里面
    String[] permissions = new String[]{Manifest.permission.ACCESS_FINE_LOCATION,Manifest.permission.ACCESS_COARSE_LOCATION};
    //2、创建一个mPermissionList，逐个判断哪些权限未授予，未授予的权限存储到mPerrrmissionList中
    List<String> mPermissionList = new ArrayList<>();
    private final int mRequestCode = 200;//权限请求码

    //权限判断和申请
    private void initPermission() {

        mPermissionList.clear();//清空没有通过的权限

        //逐个判断你要的权限是否已经通过
        for (int i = 0; i < permissions.length; i++) {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                if (checkSelfPermission( permissions[i]) != PackageManager.PERMISSION_GRANTED) {
                    mPermissionList.add(permissions[i]);//添加还未授予的权限
                }
            }
        }

        //申请权限
        if (mPermissionList.size() > 0) {//有权限没有通过，需要申请
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                requestPermissions(permissions, mRequestCode);
            }
        }
    }

    @Override
    public void onRequestPermissionsResult(int permsRequestCode, String[] permissions, int[] grantResults) {

        switch (permsRequestCode) {
            case 200:{
                initPermission();
            }break;
        }
    }

    private void initViews(){
        // 默认软键盘不弹出。改成将焦点转移到父控件,就把EditText默认的行为截断
        //getWindow().setSoftInputMode( WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN);
        btn_show_ble1 = findViewById(R.id.btn_show_ble1);
        btn_show_ble1.setSelected(true);
        show_ble = 0;
        btn_show_ble1.setOnClickListener(this);
        btn_show_ble2 = findViewById(R.id.btn_show_ble2);
        btn_show_ble2.setOnClickListener(this);
        btn_show_ble3 = findViewById(R.id.btn_show_ble3);
        btn_show_ble3.setOnClickListener(this);
        btn_show_ble4 = findViewById(R.id.btn_show_ble4);
        btn_show_ble4.setOnClickListener(this);

        btn_ble = findViewById(R.id.btn_ble);
        btn_clear_receive_data = findViewById(R.id.btn_clear_receive_data);
        btn_send_data = findViewById(R.id.btn_send_data);
        tv_device_name = findViewById(R.id.tv_device_name);

        edt_receive_data = findViewById(R.id.edt_receive_data);
        edt_receive_data.setMovementMethod(ScrollingMovementMethod.getInstance());
        edt_send_data = findViewById(R.id.edt_send_data);

        btn_ble.setOnClickListener(this);
        btn_clear_receive_data.setOnClickListener(this);
        btn_send_data.setOnClickListener(this);
        edt_send_data.addTextChangedListener(new HexTextWatcher(edt_send_data));

        waitDialog = new ProgressDialog(this);
        waitDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);// 设置进度条的形式为圆形转动的进度条
        waitDialog.setCancelable(false);// 设置是否可以通过点击Back键取消
        waitDialog.setCanceledOnTouchOutside(false);// 设置在点击Dialog外是否取消Dialog进度条
        // 设置提示的title的图标，默认是没有的，如果没有设置title的话只设置Icon是不会显示图标的
        waitDialog.setTitle(getString(R.string.list_please_wait));
        waitDialog.setMessage(getString(R.string.list_searching_ble));
        cancelDialog = new ProgressDialog(this);
        cancelDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);// 设置进度条的形式为圆形转动的进度条
        cancelDialog.setCancelable(false);// 设置是否可以通过点击Back键取消
        cancelDialog.setCanceledOnTouchOutside(false);// 设置在点击Dialog外是否取消Dialog进度条
        // 设置提示的title的图标，默认是没有的，如果没有设置title的话只设置Icon是不会显示图标的
        cancelDialog.setTitle(getString(R.string.list_please_wait));
        cancelDialog.setMessage(getString(R.string.list_disconnect_ble));
    }

    @Override
    public void onClick(View view) {
        switch (view.getId()){
            case R.id.btn_show_ble1:{
                show_ble = 0;
                tv_device_name.setText(device_name[show_ble]);
                if(mConnectionState[show_ble]){
                    btn_ble.setText(getString(R.string.list_disconnect_ble));
                }else {
                    btn_ble.setText(getString(R.string.list_connect_ble));
                }
                edt_receive_data.setText("");
                btn_show_ble1.setSelected(true);
                btn_show_ble2.setSelected(false);
                btn_show_ble3.setSelected(false);
                btn_show_ble4.setSelected(false);
            }break;
            case R.id.btn_show_ble2:{
                show_ble = 1;
                tv_device_name.setText(device_name[show_ble]);
                if(mConnectionState[show_ble]){
                    btn_ble.setText(getString(R.string.list_disconnect_ble));
                }else {
                    btn_ble.setText(getString(R.string.list_connect_ble));
                }
                edt_receive_data.setText("");
                btn_show_ble1.setSelected(false);
                btn_show_ble2.setSelected(true);
                btn_show_ble3.setSelected(false);
                btn_show_ble4.setSelected(false);
            }break;
            case R.id.btn_show_ble3:{
                show_ble = 2;
                tv_device_name.setText(device_name[show_ble]);
                if(mConnectionState[show_ble]){
                    btn_ble.setText(getString(R.string.list_disconnect_ble));
                }else {
                    btn_ble.setText(getString(R.string.list_connect_ble));
                }
                edt_receive_data.setText("");
                btn_show_ble1.setSelected(false);
                btn_show_ble2.setSelected(false);
                btn_show_ble3.setSelected(true);
                btn_show_ble4.setSelected(false);
            }break;
            case R.id.btn_show_ble4:{
                show_ble = 3;
                tv_device_name.setText(device_name[show_ble]);
                if(mConnectionState[show_ble]){
                    btn_ble.setText(getString(R.string.list_disconnect_ble));
                }else {
                    btn_ble.setText(getString(R.string.list_connect_ble));
                }
                edt_receive_data.setText("");
                btn_show_ble1.setSelected(false);
                btn_show_ble2.setSelected(false);
                btn_show_ble3.setSelected(false);
                btn_show_ble4.setSelected(true);
            }break;
            case R.id.btn_ble:{
                if(mConnectionState[show_ble]){
                    cancelDialog.show();
                    mHandler.postDelayed(new Runnable() {
                        @Override
                        public void run() {
                            cancelDialog.dismiss();
                        }
                    },1000);
                    mConnectionState[show_ble] = false;
                    btn_ble.setText(getString(R.string.list_connect_ble));
                    if (mBluetoothGatt[show_ble]!=null){
                        mBluetoothGatt[show_ble].disconnect();
                    }
                }else {
                    if(!checkBleDevice(this)){
                        return;
                    }
                    bluetoothDeviceArrayList.clear();
                    scanLeDevice(true);
                }


            }break;
            case R.id.btn_clear_receive_data:{
                edt_receive_data.setText("");
            }break;
            case R.id.btn_send_data:{
                String data = edt_send_data.getText().toString();
                sendLeData(hexToByteArray(data),show_ble);
            }break;
        }
    }

    /**
     * 判断是否支持蓝牙，并打开蓝牙
     * 获取到BluetoothAdapter之后，还需要判断是否支持蓝牙，以及蓝牙是否打开。
     * 如果没打开，需要打开蓝牙：
     */
    public boolean checkBleDevice(Context context) {
        if (mBluetoothAdapter != null) {
            if (!mBluetoothAdapter.isEnabled()) {
                boolean enable = mBluetoothAdapter.enable(); //返回值表示 是否成功打开了蓝牙功能
                if(enable){
                    Toast.makeText(context,getString(R.string.list_open_ble_success),Toast.LENGTH_SHORT).show();
                    return true;
                }else{
                    Toast.makeText(context,getString(R.string.list_open_ble_error_goto_setting),Toast.LENGTH_SHORT).show();
                    return false;
                }
            }else {
                return true;
            }
        } else {
            //Log.i("blueTooth", "该手机不支持蓝牙");
            Toast.makeText(context, getString(R.string.list_not_support_ble),Toast.LENGTH_SHORT).show();
            return false;

        }
    }

    /**
     * 搜索蓝牙设备
     */
    private void scanLeDevice(final boolean enable) {
        if (enable) {//true
            waitDialog.setMessage(getString(R.string.list_searching_ble));
            waitDialog.show();
            if(android.os.Build.VERSION.SDK_INT >= 21) {
                //标记当前的为扫描状态
                mScanning = true;
                //获取5.0新添的扫描类
                if (mBLEScanner == null){
                    //mBLEScanner是5.0新添加的扫描类，通过BluetoothAdapter实例获取。
                    mBLEScanner = mBluetoothAdapter.getBluetoothLeScanner();
                }
                //开始扫描
                //mScanCallback是ScanCallback实例，后面进行讲解。
                mBLEScanner.startScan(mScanCallback);
            } else {
                //标记当前的为扫描状态
                mScanning = true;
                //5.0以下  开始扫描
                //mLeScanCallback是BluetoothAdapter.LeScanCallback实例
                mBluetoothAdapter.startLeScan(mLeScanCallback);
            }
            //超过SCAN_TIME时间后停止搜索
            mHandler.postDelayed(new Runnable() {
                @Override
                public void run() {
                    //停止扫描设备
                    if(android.os.Build.VERSION.SDK_INT >= 21) {
                        //标记当前的为未扫描状态
                        mScanning = false;
                        mBLEScanner.stopScan(mScanCallback);
                    } else {
                        //标记当前的为未扫描状态
                        mScanning = false;
                        //5.0以下  停止扫描
                        mBluetoothAdapter.stopLeScan(mLeScanCallback);
                    }
                    waitDialog.dismiss();
                    if (bluetoothDeviceArrayList.size()>0){
                        showScanDeviceList();
                    }
                }
            }, SCAN_TIME);
        } else {//false
            if(android.os.Build.VERSION.SDK_INT >= 21) {
                //标记当前的为未扫描状态
                mScanning = false;
                mBLEScanner.stopScan(mScanCallback);
            } else {
                //标记当前的为未扫描状态
                mScanning = false;
                //5.0以下  停止扫描
                mBluetoothAdapter.stopLeScan(mLeScanCallback);
            }
            waitDialog.dismiss();
        }
    }

    /**
     * 搜索蓝牙的结果
     */
    private BluetoothAdapter.LeScanCallback mLeScanCallback = new BluetoothAdapter.LeScanCallback() {
        @Override
        public void onLeScan(final BluetoothDevice device, int rssi, byte[] scanRecord) {
            //在这里可以把搜索到的设备保存起来
            //device.getName();获取蓝牙设备名字
            //device.getAddress();获取蓝牙设备mac地址
            //这里的rssi即信号强度，即手机与设备之间的信号强度。
            if(device.getName()==null){
                return;
            }
            for(int i=0; i<bluetoothDeviceArrayList.size(); i++){
                if(device.getAddress().equals(bluetoothDeviceArrayList.get(i).getAddress())){
                    return;
                }
            }
            bluetoothDeviceArrayList.add(device);
        }
    };
    private ScanCallback mScanCallback = new ScanCallback() {
        //当一个蓝牙ble广播被发现时回调
        @Override
        public void onScanResult(int callbackType, ScanResult result) {
            super.onScanResult(callbackType, result);
            //扫描类型有开始扫描时传入的ScanSettings相关
            //对扫描到的设备进行操作。如：获取设备信息。
            BluetoothDevice device = result.getDevice();
            if(device.getName()==null){
                return;
            }
            for(int i=0; i<bluetoothDeviceArrayList.size(); i++){
                if(device.getAddress().equals(bluetoothDeviceArrayList.get(i).getAddress())){
                    return;
                }
            }
            bluetoothDeviceArrayList.add(device);
        }

        //批量返回扫描结果
        //@param results 以前扫描到的扫描结果列表。
        @Override
        public void onBatchScanResults(List<ScanResult> results) {
            super.onBatchScanResults(results);

        }

        //当扫描不能开启时回调
        @Override
        public void onScanFailed(int errorCode) {
            super.onScanFailed(errorCode);
            //扫描太频繁会返回ScanCallback.SCAN_FAILED_APPLICATION_REGISTRATION_FAILED，表示app无法注册，无法开始扫描。
            //android 7.0后不能在30秒内扫描次数超过5次

        }
    };

    private void showScanDeviceList(){
        final String[] deviceNames = new String[bluetoothDeviceArrayList.size()];
        for (int i = 0; i < bluetoothDeviceArrayList.size(); i++) {
            if (bluetoothDeviceArrayList.get(i).getName() == null) {
                deviceNames[i] = "Unknow";
            } else {
                deviceNames[i] = bluetoothDeviceArrayList.get(i).getName();
            }
        }
        new AlertDialog.Builder(this).setTitle(getString(R.string.list_select_ble))
                .setSingleChoiceItems(deviceNames, -1, new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int item) {
                        selIndex = item;
                    }
                }).setPositiveButton(getString(R.string.list_ok), new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int which) {

                waitDialog.setMessage(getString(R.string.list_connecting_ble));
                waitDialog.show();
                connectLeDevice(bluetoothDeviceArrayList.get(selIndex).getAddress());
            }
        }).setNegativeButton(getString(R.string.list_cancel), new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int which) {
            }
        }).show();
    }

    /**
     *连接的时候，我们可以通过搜索到的mac地址来进行连接
     * @param address
     * @return
     */

    public boolean connectLeDevice(final String address) {
        Log.d(TAG, "连接" + address);
        if (mBluetoothAdapter == null || address == null) {
            Log.d(TAG,"BluetoothAdapter不能初始化 or 未知 address.");
            return false;
        }


        final BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(address);
        if (device == null) {
            Log.d(TAG, "设备没找到，不能连接");
            return false;
        }

        if(mBluetoothGatt[show_ble]!=null){
            mBluetoothGatt[show_ble].close();
        }
        fourReadCharacteristicArrayList.get(show_ble).clear();
        fourWriteCharacteristicArrayList.get(show_ble).clear();
        fourNotifyCharacteristicArrayList.get(show_ble).clear();
        mBluetoothGatt[show_ble] = device.connectGatt(this, false, mGattCallback);//真正的连接
        //这个方法需要三个参数：一个Context对象，自动连接（boolean值,表示只要BLE设备可用是否自动连接到它），和BluetoothGattCallback调用。
        return true;
    }

    /**
     * BluetoothGattCallback用于传递一些连接状态及结果，在这处理各种连接状态
     */
    private final BluetoothGattCallback mGattCallback = new BluetoothGattCallback() {
        @Override
        public void onConnectionStateChange(BluetoothGatt gatt, int status,
                                            int newState) {
            Log.d(TAG, "status" + status+",newSatate"+newState);
            if (newState == BluetoothProfile.STATE_CONNECTED) {//当连接状态发生改变
                if (mBluetoothGatt[show_ble] == gatt){
                    mConnectionState[show_ble] = true;
                    // 连接成功后尝试发现服务
                    gatt.discoverServices();
                    mHandler.post(new Runnable() {
                        @Override
                        public void run() {
                            //做连接后的变化
                            btn_ble.setText(getString(R.string.list_disconnect_ble));
                            device_name[show_ble] = mBluetoothGatt[show_ble].getDevice().getName();
                            tv_device_name.setText("" + device_name[show_ble]);
                            waitDialog.dismiss();
                        }
                    });
                }else {
                    for (int i=0; i< 4; i++){
                        if (mBluetoothGatt[i] == gatt){
                            mConnectionState[i] = true;
                            gatt.discoverServices();
                            device_name[i] = mBluetoothGatt[i].getDevice().getName();
                        }
                    }
                }

            } else if (newState == BluetoothProfile.STATE_DISCONNECTED) {//当设备无法连接
                if (mBluetoothGatt[show_ble] == gatt){
                    mConnectionState[show_ble] = false;
                    if(mBluetoothGatt[show_ble]!=null){
                        mBluetoothGatt[show_ble].close();
                    }
                    mHandler.post(new Runnable() {
                        @Override
                        public void run() {
                            //未连接
                            waitDialog.dismiss();
                            btn_ble.setText(getString(R.string.list_connect_ble));
                            device_name[show_ble] = "";
                            tv_device_name.setText("");
                        }
                    });
                }else {
                    for (int i=0; i< 4; i++){
                        if (mBluetoothGatt[i] == gatt){
                            mConnectionState[i] = false;
                            if(mBluetoothGatt[i]!=null){
                                mBluetoothGatt[i].close();
                            }
                            device_name[i] = mBluetoothGatt[i].getDevice().getName();
                        }
                    }
                }

            }
        }


        @Override
        // 发现新服务，即调用了mBluetoothGatt.discoverServices()后，返回的数据
        public void onServicesDiscovered(BluetoothGatt gatt, int status) {
            if (status == BluetoothGatt.GATT_SUCCESS) {
                if (mBluetoothGatt[show_ble] == gatt){
                    if (USE_SPECIFIC_UUID){
                        //获取指定uuid的service
                        BluetoothGattService gattService = mBluetoothGatt[show_ble].getService(mServiceUUID);
                        //获取到特定的服务不为空
                        if(gattService != null) {
                            //获取指定uuid的Characteristic
                            BluetoothGattCharacteristic gattCharacteristic = gattService.getCharacteristic(mCharacteristicUUID);
                            //获取特定特征成功
                            if (gattCharacteristic != null) {
                                fourReadCharacteristicArrayList.get(show_ble).add(gattCharacteristic);
                                fourWriteCharacteristicArrayList.get(show_ble).add(gattCharacteristic);
                                fourNotifyCharacteristicArrayList.get(show_ble).add(gattCharacteristic);
                            }
                        }
                    }else {
                        //得到所有Service
                        List<BluetoothGattService> supportedGattServices = gatt.getServices();
                        for (BluetoothGattService gattService : supportedGattServices) {
                            //得到每个Service的Characteristics
                            List<BluetoothGattCharacteristic> gattCharacteristics = gattService.getCharacteristics();
                            for (BluetoothGattCharacteristic gattCharacteristic : gattCharacteristics) {
                                int charaProp = gattCharacteristic.getProperties();
                                //所有Characteristics按属性分类
                                if ((charaProp | BluetoothGattCharacteristic.PROPERTY_READ) > 0) {
                                    fourReadCharacteristicArrayList.get(show_ble).add(gattCharacteristic);
                                }
                                if ((charaProp | BluetoothGattCharacteristic.PROPERTY_WRITE) > 0) {
                                    fourWriteCharacteristicArrayList.get(show_ble).add(gattCharacteristic);
                                }
                                if ((charaProp | BluetoothGattCharacteristic.PROPERTY_NOTIFY) > 0) {
                                    fourNotifyCharacteristicArrayList.get(show_ble).add(gattCharacteristic);
                                }
                            }
                        }
                    }
                    setmBluetoothGattNotification(show_ble);
                }else {
                    for (int i=0; i< 4; i++){
                        if (mBluetoothGatt[i] == gatt){
                            if (USE_SPECIFIC_UUID){
                                //获取指定uuid的service
                                BluetoothGattService gattService = mBluetoothGatt[i].getService(mServiceUUID);
                                //获取到特定的服务不为空
                                if(gattService != null) {
                                    //获取指定uuid的Characteristic
                                    BluetoothGattCharacteristic gattCharacteristic = gattService.getCharacteristic(mCharacteristicUUID);
                                    //获取特定特征成功
                                    if (gattCharacteristic != null) {
                                        fourReadCharacteristicArrayList.get(i).add(gattCharacteristic);
                                        fourWriteCharacteristicArrayList.get(i).add(gattCharacteristic);
                                        fourNotifyCharacteristicArrayList.get(i).add(gattCharacteristic);
                                    }
                                }
                            }else {
                                //得到所有Service
                                List<BluetoothGattService> supportedGattServices = gatt.getServices();
                                for (BluetoothGattService gattService : supportedGattServices) {
                                    //得到每个Service的Characteristics
                                    List<BluetoothGattCharacteristic> gattCharacteristics = gattService.getCharacteristics();
                                    for (BluetoothGattCharacteristic gattCharacteristic : gattCharacteristics) {
                                        int charaProp = gattCharacteristic.getProperties();
                                        //所有Characteristics按属性分类
                                        if ((charaProp | BluetoothGattCharacteristic.PROPERTY_READ) > 0) {
                                            fourReadCharacteristicArrayList.get(i).add(gattCharacteristic);
                                        }
                                        if ((charaProp | BluetoothGattCharacteristic.PROPERTY_WRITE) > 0) {
                                            fourWriteCharacteristicArrayList.get(i).add(gattCharacteristic);
                                        }
                                        if ((charaProp | BluetoothGattCharacteristic.PROPERTY_NOTIFY) > 0) {
                                            fourNotifyCharacteristicArrayList.get(i).add(gattCharacteristic);
                                        }
                                    }
                                }
                            }
                            setmBluetoothGattNotification(i);
                        }
                    }
                }

            } else {
                Log.i(TAG, "onServicesDiscovered received: " + status);
            }
        }

        // 读写特性
        @Override
        public void onCharacteristicRead(BluetoothGatt gatt,
                                         BluetoothGattCharacteristic characteristic, int status) {
            if (status == BluetoothGatt.GATT_SUCCESS) {
                final byte[] desData = characteristic.getValue();
                Log.i(TAG,"onCharacteristicRead:"+desData.toString());
            }
        }

        @Override
        public void onDescriptorWrite(BluetoothGatt gatt,
                                      BluetoothGattDescriptor descriptor, int status) {
            Log.i(TAG,"onDescriptorWrite");
        }

        //如果对一个特性启用通知,当远程蓝牙设备特性发送变化，回调函数onCharacteristicChanged( ))被触发。
        @Override
        public void onCharacteristicChanged(BluetoothGatt gatt,
                                            BluetoothGattCharacteristic characteristic) {
            final byte[] desData = characteristic.getValue();
            //Log.i(TAG,"onCharacteristicChanged:"+desData.toString());
            if (mBluetoothGatt[show_ble] == gatt){
                mHandler.post(new Runnable() {
                    @Override
                    public void run() {

                        if (edt_receive_data.getText().length()>100){
                            edt_receive_data.setText("");
                        }
                        edt_receive_data.setText(edt_receive_data.getText()+" "+bytesToHex(desData));
                    }
                });
            }

        }
        @Override
        public void onReadRemoteRssi(BluetoothGatt gatt, int rssi, int status) {
            //mBluetoothGatt.readRemoteRssi()调用得到，rssi即信号强度，做防丢器时可以不断使用此方法得到最新的信号强度，从而得到距离。
        }

        public void onCharacteristicWrite(BluetoothGatt gatt,
                                          BluetoothGattCharacteristic characteristic, int status) {

            System.out.println("--------write success----- status:" + status);
        }
    };

    /**
     * 设置蓝牙notification功能，如果有接受到数据
     */
    private void setmBluetoothGattNotification(int device_index){
//        List<BluetoothGattCharacteristic> characteristicArrayList = fourReadCharacteristicArrayList.get(device_index);
        List<BluetoothGattCharacteristic> characteristicArrayList = fourNotifyCharacteristicArrayList.get(device_index);
        for (int i=0; i<characteristicArrayList.size(); i++){
            BluetoothGattCharacteristic characteristic = characteristicArrayList.get(i);
            mBluetoothGatt[device_index].setCharacteristicNotification(characteristic, true);
            // enable remote notification
            List<BluetoothGattDescriptor> gattDescriptors = characteristic.getDescriptors();
            for (BluetoothGattDescriptor gattDescriptor : gattDescriptors) {
                gattDescriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
                mBluetoothGatt[device_index].writeDescriptor(gattDescriptor);
            }
        }
    }

    /**
     * 蓝牙发送数据
     * @param byteArray
     */
    private void sendLeData(byte byteArray[],int device_index){
        List<BluetoothGattCharacteristic> writeCharacteristicArrayList = fourWriteCharacteristicArrayList.get(device_index);
        for (int i=0; i<writeCharacteristicArrayList.size(); i++){
            BluetoothGattCharacteristic characteristic = writeCharacteristicArrayList.get(i);
            characteristic.setValue(byteArray);
            mBluetoothGatt[device_index].writeCharacteristic(characteristic);
        }
    }

    public static String bytesToHex(byte[] bytes) {
        char[] hexChars = new char[bytes.length * 2];
        char[] hexArray = "0123456789ABCDEF".toCharArray();
        for (int j = 0; j < bytes.length; j++) {
            int v = bytes[j] & 0xFF;
            hexChars[j * 2] = hexArray[v >>> 4];
            hexChars[j * 2 + 1] = hexArray[v & 0x0F];
        }
        return new String(hexChars);
    }

    public static byte[] hexToByteArray(String hexString) {
        int hexlen = hexString.length();
        byte[] result;
        if (hexlen % 2 == 1){
            //奇数
            hexlen++;
            result = new byte[(hexlen/2)];
            hexString="0"+hexString;
        }else {
            //偶数
            result = new byte[(hexlen/2)];
        }
        int j=0;
        for (int i = 0; i < hexlen; i+=2){
            result[j]= (byte) Integer.parseInt(hexString.substring(i,i+2),16);
            j++;
        }
        return result;

    }

}
